﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace Gmantis.Controls
{
    public class KeyboardUtil
    {
        // Fields
        private static bool _alt;
        private static Dictionary<int, char> _charMap;
        private static bool _ctrl;
        private static bool _shift;

        // Methods
        private static Dictionary<int, char> GetCharacterMap()
        {
            if (_charMap == null)
            {
                _charMap = new Dictionary<int, char>();
                Dictionary<int, char> dictionary = _charMap;
                if (Environment.OSVersion.Platform == PlatformID.MacOSX)
                {
                    dictionary[-2353] = ' ';
                    dictionary[-5149] = '0';
                    dictionary[-5394] = '1';
                    dictionary[-5651] = '2';
                    dictionary[-5908] = '3';
                    dictionary[-6165] = '4';
                    dictionary[-6423] = '5';
                    dictionary[-6678] = '6';
                    dictionary[-6938] = '7';
                    dictionary[-7196] = '8';
                    dictionary[-7449] = '9';
                    dictionary[-7680] = 'a';
                    dictionary[-7947] = 'b';
                    dictionary[-8200] = 'c';
                    dictionary[-8450] = 'd';
                    dictionary[-8718] = 'e';
                    dictionary[-8963] = 'f';
                    dictionary[-9221] = 'g';
                    dictionary[-9476] = 'h';
                    dictionary[-9762] = 'i';
                    dictionary[-10022] = 'j';
                    dictionary[-10280] = 'k';
                    dictionary[-10533] = 'l';
                    dictionary[-10798] = 'm';
                    dictionary[-11053] = 'n';
                    dictionary[-11295] = 'o';
                    dictionary[-11555] = 'p';
                    dictionary[-11788] = 'q';
                    dictionary[-12047] = 'r';
                    dictionary[-12289] = 's';
                    dictionary[-12561] = 't';
                    dictionary[-12832] = 'u';
                    dictionary[-13065] = 'v';
                    dictionary[-13325] = 'w';
                    dictionary[-13575] = 'x';
                    dictionary[-13840] = 'y';
                    dictionary[-14086] = 'z';
                    dictionary[-65321] = ';';
                    dictionary[-65304] = '=';
                    dictionary[-65323] = ',';
                    dictionary[-65307] = '-';
                    dictionary[-65327] = '.';
                    dictionary[-65324] = '/';
                    dictionary[-65330] = '`';
                    dictionary[-65313] = '[';
                    dictionary[-65322] = '\\';
                    dictionary[-65310] = ']';
                    dictionary[-65319] = '\'';
                    dictionary[0x931] = ' ';
                    dictionary[0x141d] = ')';
                    dictionary[0x1512] = '!';
                    dictionary[0x1613] = '@';
                    dictionary[0x1714] = '#';
                    dictionary[0x1815] = '$';
                    dictionary[0x1917] = '%';
                    dictionary[0x1a16] = '^';
                    dictionary[0x1b1a] = '&';
                    dictionary[0x1c1c] = '*';
                    dictionary[0x1d19] = '(';
                    dictionary[0x1e00] = 'A';
                    dictionary[0x1f0b] = 'B';
                    dictionary[0x2008] = 'C';
                    dictionary[0x2102] = 'D';
                    dictionary[0x220e] = 'E';
                    dictionary[0x2303] = 'F';
                    dictionary[0x2405] = 'G';
                    dictionary[0x2504] = 'H';
                    dictionary[0x2622] = 'I';
                    dictionary[0x2726] = 'J';
                    dictionary[0x2828] = 'K';
                    dictionary[0x2925] = 'L';
                    dictionary[0x2a2e] = 'M';
                    dictionary[0x2b2d] = 'N';
                    dictionary[0x2c1f] = 'O';
                    dictionary[0x2d23] = 'P';
                    dictionary[0x2e0c] = 'Q';
                    dictionary[0x2f0f] = 'R';
                    dictionary[0x3001] = 'S';
                    dictionary[0x3111] = 'T';
                    dictionary[0x3220] = 'U';
                    dictionary[0x3309] = 'V';
                    dictionary[0x340d] = 'W';
                    dictionary[0x3507] = 'X';
                    dictionary[0x3610] = 'Y';
                    dictionary[0x3706] = 'Z';
                    dictionary[0xff29] = ':';
                    dictionary[0xff18] = '+';
                    dictionary[0xff2b] = '<';
                    dictionary[0xff1b] = '_';
                    dictionary[0xff2f] = '>';
                    dictionary[0xff2c] = '?';
                    dictionary[0xff32] = '~';
                    dictionary[0xff21] = '{';
                    dictionary[0xff2a] = '|';
                    dictionary[0xff1e] = '}';
                    dictionary[0xff27] = '"';
                    dictionary[-17490] = '0';
                    dictionary[-17747] = '1';
                    dictionary[-18004] = '2';
                    dictionary[-18261] = '3';
                    dictionary[-18518] = '4';
                    dictionary[-18775] = '5';
                    dictionary[-19032] = '6';
                    dictionary[-19289] = '7';
                    dictionary[-19547] = '8';
                    dictionary[-19804] = '9';
                    dictionary[-20293] = '+';
                    dictionary[-20558] = '-';
                    dictionary[-21067] = '/';
                    dictionary[-20035] = '*';
                    dictionary[-20801] = '.';
                }
                else
                {
                    dictionary[-2336] = ' ';
                    dictionary[-5168] = '0';
                    dictionary[-5425] = '1';
                    dictionary[-5682] = '2';
                    dictionary[-5939] = '3';
                    dictionary[-6196] = '4';
                    dictionary[-6453] = '5';
                    dictionary[-6710] = '6';
                    dictionary[-6967] = '7';
                    dictionary[-7224] = '8';
                    dictionary[-7481] = '9';
                    dictionary[-7745] = 'a';
                    dictionary[-8002] = 'b';
                    dictionary[-8259] = 'c';
                    dictionary[-8516] = 'd';
                    dictionary[-8773] = 'e';
                    dictionary[-9030] = 'f';
                    dictionary[-9287] = 'g';
                    dictionary[-9544] = 'h';
                    dictionary[-9801] = 'i';
                    dictionary[-10058] = 'j';
                    dictionary[-10315] = 'k';
                    dictionary[-10572] = 'l';
                    dictionary[-10829] = 'm';
                    dictionary[-11086] = 'n';
                    dictionary[-11343] = 'o';
                    dictionary[-11600] = 'p';
                    dictionary[-11857] = 'q';
                    dictionary[-12114] = 'r';
                    dictionary[-12371] = 's';
                    dictionary[-12628] = 't';
                    dictionary[-12885] = 'u';
                    dictionary[-13142] = 'v';
                    dictionary[-13399] = 'w';
                    dictionary[-13656] = 'x';
                    dictionary[-13913] = 'y';
                    dictionary[-14170] = 'z';
                    dictionary[-65466] = ';';
                    dictionary[-65467] = '=';
                    dictionary[-65468] = ',';
                    dictionary[-65469] = '-';
                    dictionary[-65470] = '.';
                    dictionary[-65471] = '/';
                    dictionary[-65472] = '`';
                    dictionary[-65499] = '[';
                    dictionary[-65500] = '\\';
                    dictionary[-65501] = ']';
                    dictionary[-65502] = '\'';
                    dictionary[0x920] = ' ';
                    dictionary[0x1430] = ')';
                    dictionary[0x1531] = '!';
                    dictionary[0x1632] = '@';
                    dictionary[0x1733] = '#';
                    dictionary[0x1834] = '$';
                    dictionary[0x1935] = '%';
                    dictionary[0x1a36] = '^';
                    dictionary[0x1b37] = '&';
                    dictionary[0x1c38] = '*';
                    dictionary[0x1d39] = '(';
                    dictionary[0x1e41] = 'A';
                    dictionary[0x1f42] = 'B';
                    dictionary[0x2043] = 'C';
                    dictionary[0x2144] = 'D';
                    dictionary[0x2245] = 'E';
                    dictionary[0x2346] = 'F';
                    dictionary[0x2447] = 'G';
                    dictionary[0x2548] = 'H';
                    dictionary[0x2649] = 'I';
                    dictionary[0x274a] = 'J';
                    dictionary[0x284b] = 'K';
                    dictionary[0x294c] = 'L';
                    dictionary[0x2a4d] = 'M';
                    dictionary[0x2b4e] = 'N';
                    dictionary[0x2c4f] = 'O';
                    dictionary[0x2d50] = 'P';
                    dictionary[0x2e51] = 'Q';
                    dictionary[0x2f52] = 'R';
                    dictionary[0x3053] = 'S';
                    dictionary[0x3154] = 'T';
                    dictionary[0x3255] = 'U';
                    dictionary[0x3356] = 'V';
                    dictionary[0x3457] = 'W';
                    dictionary[0x3558] = 'X';
                    dictionary[0x3659] = 'Y';
                    dictionary[0x375a] = 'Z';
                    dictionary[0xffba] = ':';
                    dictionary[0xffbb] = '+';
                    dictionary[0xffbc] = '<';
                    dictionary[0xffbd] = '_';
                    dictionary[0xffbe] = '>';
                    dictionary[0xffbf] = '?';
                    dictionary[0xffc0] = '~';
                    dictionary[0xffdb] = '{';
                    dictionary[0xffdc] = '|';
                    dictionary[0xffdd] = '}';
                    dictionary[0xffde] = '"';
                    dictionary[-17504] = '0';
                    dictionary[-17761] = '1';
                    dictionary[-18018] = '2';
                    dictionary[-18275] = '3';
                    dictionary[-18532] = '4';
                    dictionary[-18789] = '5';
                    dictionary[-19046] = '6';
                    dictionary[-19303] = '7';
                    dictionary[-19560] = '8';
                    dictionary[-19817] = '9';
                    dictionary[-20331] = '+';
                    dictionary[-20589] = '-';
                    dictionary[-21103] = '/';
                    dictionary[-20074] = '*';
                    dictionary[-20846] = '.';
                }
            }
            return _charMap;
        }

        internal static KeyEventArgs GetKeyArgs(char c)
        {
            foreach (KeyValuePair<int, char> pair in GetCharacterMap())
            {
                if (pair.Value == c)
                {
                    return new KeyEventArgs { Key = (Key)(Math.Abs(pair.Key) >> 8), PlatformKeyCode = Math.Abs(pair.Key) & 0xff };
                }
            }
            return new KeyEventArgs();
        }

        internal static string GetKeyString(Gmantis.Controls.KeyEventArgs e)
        {
            if (!Ctrl)
            {
                char ch;
                int key = (e.Key.GetHashCode() * 0x100) + e.PlatformKeyCode;
                if (!Shift)
                {
                    key *= -1;
                }
                if (GetCharacterMap().TryGetValue(key, out ch))
                {
                    return new string(ch, 1);
                }
            }
            return null;
        }

        public static string GetKeyString(System.Windows.Input.KeyEventArgs e)
        {
            return GetKeyString(new KeyEventArgs(e));
        }

        // Properties
        public static bool Alt
        {
            get
            {
                if ((Keyboard.Modifiers & ModifierKeys.Alt) <= ModifierKeys.None)
                {
                    return _alt;
                }
                return true;
            }
            internal set
            {
                _alt = value;
            }
        }

        internal static bool Command
        {
            get
            {
                return ((Keyboard.Modifiers & (ModifierKeys.Apple | ModifierKeys.Control)) > ModifierKeys.None);
            }
        }

        public static bool Ctrl
        {
            get
            {
                if ((Keyboard.Modifiers & ModifierKeys.Control) <= ModifierKeys.None)
                {
                    return _ctrl;
                }
                return true;
            }
            internal set
            {
                _ctrl = value;
            }
        }

        public static bool Shift
        {
            get
            {
                if ((Keyboard.Modifiers & ModifierKeys.Shift) <= ModifierKeys.None)
                {
                    return _shift;
                }
                return true;
            }
            internal set
            {
                _shift = value;
            }
        }
    }
}
